package com.cj.myblog.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.cj.myblog.constants.ResultEnum;
import com.cj.myblog.common.util.CommUtil;
import com.cj.myblog.common.util.PageUtil;
import com.cj.myblog.dao.ArticleContentRepository;
import com.cj.myblog.dao.ArticleRepository;
import com.cj.myblog.dao.CommentRepository;
import com.cj.myblog.dao.TagRepository;
import com.cj.myblog.dao.specification.SimpleSpecificationBuilder;
import com.cj.myblog.model.*;
import com.cj.myblog.service.ArticleService;
import com.xiaoleilu.hutool.util.BeanUtil;
import com.xiaoleilu.hutool.util.StrUtil;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Created by Administrator on 2017-08-30.
 */
@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private ArticleRepository articleRepository;

    @Autowired
    private TagRepository tagRepository;

    @Autowired
    private ArticleContentRepository articleContentRepository;

    @Autowired
    private CommentRepository commentRepository;


    @Override
    public PageBean<ArticleDo> findAll(final ArticleDo articleDo) {

        Page<ArticleDo> list = null;
        Pageable pageable = PageUtil.buildPageRequest(articleDo.getStart(),articleDo.getLength(),"createTime");

        if (StrUtil.isNotEmpty(articleDo.getTags())){
            TagDo tag = tagRepository.findAllByTag(articleDo.getTags());
            list = articleRepository.findAllArticleByTag(tag.getId().toString(),pageable);
        }else {
            list = articleRepository.findAll(
                    new SimpleSpecificationBuilder()
                            .add("title",":",articleDo.getTitle()).add("createTime","between",articleDo.getBeginTime(),articleDo.getEndTime())
                            .add("partId","=",articleDo.getPartId())
                            .generateSpecification()
            , pageable);
        }

        return new PageBean<>(list);
    }

    @Override
    @Transactional
    public void deleteByIdIn(List<Long> idList) {
        articleRepository.deleteByIdIn(idList);
        articleContentRepository.deleteByArticleIdIn(idList);
    }


    @Override
    public ArticleDo findById(Long id) {
        ArticleDo articleDo = articleRepository.findOne(id);

        ArticleContentDo articleContentDo = articleContentRepository.findOne(id);

        //根据tag id 查找tag名称,并且根据,拼接
        if (!"".equals(articleDo.getTags().trim())){

            List<String> tagIdList = StrUtil.split(articleDo.getTags(),',');

            List<TagDo> tagList = tagRepository.findAllByIdIn(CommUtil.stringToLongList(tagIdList));

            List<String> newTagList = new ArrayList<>();

            for (TagDo tagDo:tagList) {
                newTagList.add(tagDo.getTag());
            }

            articleDo.setTags(StrUtil.join(",",newTagList));
        }

        articleDo.setContent(CommUtil.htmlspecialchars(articleContentDo.getContent()));
        articleDo.setSubject(CommUtil.htmlspecialchars(articleDo.getSubject()));
        articleDo.setDirectory(articleContentDo.getDirectory());

        return articleDo;
    }

    @Override
    @Transactional
    public Result<String> save(ArticleDo articleDo) {
        //处理新增的tag标签
        List<String> tagList = StrUtil.split(articleDo.getTags(),',');
        List<String> newTagList = new ArrayList<>();
        for (int i=0;i<tagList.size();i++) {
            String str = tagList.get(i).trim();
            if (StrUtil.isNotEmpty(str)){
                TagDo tag = tagRepository.findAllByTag(str);
                if (tag == null){
                    TagDo tagDo = new TagDo();
                    tagDo.setTag(str);
                    tag = tagRepository.save(tagDo);
                }
                newTagList.add(tag.getId().toString());
            }
        }

        articleDo.setTags(StrUtil.join(",",newTagList));
        articleDo.setModifyTime(new Date());
        ArticleDo DO = null;
       if (articleDo.getId() == null){
           articleDo.setCreateTime(new Date());
           articleDo.setHits(0);
           DO = articleRepository.save(articleDo);
       }else {
           DO = articleRepository.findOne(articleDo.getId());
           BeanUtil.copyProperties(articleDo,DO, BeanUtil.CopyOptions.create().setIgnoreNullValue(true));
       }

        if (DO == null){
            return new Result<>(ResultEnum.SAVE_ERROR);
        }else {
            String content = articleDo.getContent();
            List<Map<String,Object>> mapList = new ArrayList<>();

            if (articleDo.getIsDirectory() == 1){
                Document document = Jsoup.parse(articleDo.getContent());
                Elements elementsH1 = document.select("h1");
                Elements elementsH2 = document.select("h2");
                for(int i=0;i<elementsH1.size();i++){
                    Element element = elementsH1.get(i);
                    String regx = element.html();
                    element.attr("id",element.text());
                    content.replaceAll(regx,element.html());
                    Map<String,Object> map = new HashMap<>();
                    map.put("id",i+1);
                    map.put("pId",0);
                    map.put("name",element.text());
                    map.put("open",true);
                    map.put("url","#"+element.text());
                    map.put("target","_self");
                    mapList.add(map);
                }

                for(int i=0;i<elementsH2.size();i++){
                    Element element = elementsH2.get(i);
                    element.attr("id",element.text());
                }

            }

            ArticleContentDo articleContentDo = new ArticleContentDo();
            articleContentDo.setArticleId(DO.getId());
            articleContentDo.setContent(content);
            articleContentDo.setDirectory(JSONObject.toJSONString(mapList));
            ArticleContentDo contentDO = articleContentRepository.save(articleContentDo);
        }
        return new Result<>();
    }


    @Override
    public List<ArticleDo> frontFindAll(ArticleDo articleDo) {
        Pageable pageable = PageUtil.buildPageRequest(articleDo.getStart(),articleDo.getLength(),"createTime");
        Page<ArticleDo>  list = articleRepository.findAll(
                new SimpleSpecificationBuilder()
                        .add("title",":",articleDo.getTitle())
                        .add("partId","=",articleDo.getPartId())
                        .add("status","!=",0)
                        .generateSpecification()
                , pageable);

        List<ArticleDo> articleDoList = list.getContent();
        List<ArticleDo> returnList = new ArrayList<>();
        for (ArticleDo article:articleDoList) {
            if (!"".equals(article.getTags().trim())) {
                List<String> tagIdList = StrUtil.split(article.getTags(), ',');
                List<TagDo> tagList = tagRepository.findAllByIdIn(CommUtil.stringToLongList(tagIdList));
                int commentCount = commentRepository.getCountByArtId(article.getId());
                article.setCommentCount(commentCount);
                article.setTagDoList(tagList);
            }else {
                article.setTagDoList(new ArrayList<TagDo>());
            }
            if (article.getStatus() == 2){
                returnList.add(0,article);
            }else {
                returnList.add(article);
            }
        }

        return returnList;
    }


    @Override
    @Transactional
    public ArticleDo frontFindById(Long id) {
        //文章基本信息
        ArticleDo articleDo = articleRepository.findOne(id);
        //文章内容
        ArticleContentDo articleContentDo = articleContentRepository.findOne(id);

        //根据tag id 查找tag名称
        if (!"".equals(articleDo.getTags().trim())){

            List<String> tagIdList = StrUtil.split(articleDo.getTags(),',');

            List<TagDo> tagList = tagRepository.findAllByIdIn(CommUtil.stringToLongList(tagIdList));

            articleDo.setTagDoList(tagList);
        }else {
            articleDo.setTagDoList(new ArrayList<TagDo>());
        }

        articleDo.setContent(articleContentDo.getContent());
        articleDo.setDirectory(articleContentDo.getDirectory());

        return articleDo;
    }




}


